package com.han.controllers;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.han.bom.Exam;
import com.han.bom.PracticeExam;
import com.han.bom.Professor;
import com.han.bom.Question;
import com.han.bom.RealExam;
import com.han.bom.Student;
import com.han.bom.utilities.Message;
import com.han.dao.concrete.product.AnswerDAO;
import com.han.dao.concrete.product.ExamDAO;
import com.han.dao.concrete.product.QuestionDAO;
import com.han.dao.concrete.product.UserDAO;

/**
 * Servlet implementation class CreateExamServlet
 */
@WebServlet("/Professor/AddAndEditExamServlet")
public class AddAndEditExamServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private static Logger logger = Logger.getLogger(AddAndEditExamServlet.class.getName());

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public AddAndEditExamServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	@SuppressWarnings("unchecked")
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		logger.info("Entered AddAndEditExamServlet POST");

		Professor professor =  null;
		HttpSession session = request.getSession();
		String examName=null,examDuration=null,examPassing=null,examQuestions=null,examStudents=null,examType=null,examID=null;
		QuestionDAO questiondao = new QuestionDAO();
		AnswerDAO answerdao = new AnswerDAO();
		boolean editMode = false;

		if(session.getAttribute("professor")!=null){
			professor = (Professor) session.getAttribute("professor");
		}
		else{

		}

		if(request.getParameter("examName")!=null){
			examName = request.getParameter("examName");
		}
		else{

		}

		if(request.getParameter("type")!=null){
			examType = request.getParameter("type");
		}
		else{

		}

		if(request.getParameter("examID")!=null){
			examID = request.getParameter("examID");
			editMode = true;
		}
		else{
			examID = null;
		}

		if(examType.equals("Real")){

			if(request.getParameter("examDuration")!=null){
				examDuration = request.getParameter("examDuration");
			}
			else{

			}

			if(request.getParameter("examPassing")!=null){
				examPassing = request.getParameter("examPassing");
			}
			else{

			}

			if(request.getParameter("examStudents")!=null){
				examStudents = request.getParameter("examStudents");
			}
			else{

			}
		}

		if(request.getParameter("examQuestions")!=null){
			examQuestions =request.getParameter("examQuestions");
		}
		else{

		}


		Exam exam = null;
		ArrayList<Question> questions = new ArrayList<Question>();

		if(!examQuestions.equals("0")){
			for(String questionID: examQuestions.split(",")){
				Question question=null;
				ArrayList<String> choices=null;
				try {
					question = questiondao.retrieveQuestionById(questionID);

					choices = answerdao.retrieveAnswersByQuestion(questionID);
				} catch (ClassNotFoundException e) {

					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (SQLException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (NamingException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}

				question.setChoices(choices);
				question.setAnswer(choices.get(0));

				questions.add(question);
			}
		}

		ExamDAO examdao = new ExamDAO();

		int max=-1;
		try {
			max = examdao.retrieveMaxExamID();
		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		} catch (SQLException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		} catch (NamingException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

		if(examID != null){

			if("Real".equals(examType)){
				try {
					exam = examdao.retrieveExamById(examID);
					exam.setExamName(examName);
					exam.setDuration(Long.parseLong(examDuration));
					exam.setPassingPercent(Double.parseDouble(examPassing));
					exam.setQuestions(questiondao.retrieveQuestionsbyExam(exam.getExamID()));
				} catch (ClassNotFoundException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (SQLException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (NamingException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}
			}
			else{
				try {
					exam = examdao.retrieveExamById(examID);
					exam.setExamName(examName);
					exam.setQuestions(questiondao.retrieveQuestionsbyExam(exam.getExamID()));
				} catch (ClassNotFoundException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (SQLException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (NamingException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}
			}
		}
		else{
			if(examType.equals("Real")){
				exam = new RealExam(examName, questions);
				exam.setExamID("E"+(max)+"RE");
				exam.setDuration(Long.parseLong(examDuration));
				exam.setPassingPercent(Double.parseDouble(examPassing));
			}
			else if(examType.equals("Practice")){
				exam = new PracticeExam(examName, questions);
				exam.setExamID("E"+(max)+"PE");
			}
			else{

			}
		}

		try {
			if(examID==null){ //new exam
				examdao.insertExam(exam, professor.getUserID());
			}
			else{ //update exam
				examdao.updateExam(exam);				
			}

			questiondao.removeAllQuestionsFromExam(exam.getExamID());

			for(Question question: questions){ //add new questions
				questiondao.addQuestionToExam(question.getQuestionID(), exam.getExamID());
			}

		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		} catch (SQLException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		} catch (NamingException e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

		UserDAO userdao = new UserDAO();

		ArrayList<String> studentIDNew = new ArrayList<String>();

		if("Real".equals(examType)){
			for(String studentID: examStudents.split(",")){
				studentIDNew.add(studentID);
			}
		}

		if(examID != null){

			ArrayList<Student> studentsTakingExam = null;
			try {
				studentsTakingExam = userdao.retrieveStudentsIncludedInExam(examID);
			} catch (ClassNotFoundException e1) {
				logger.error(e1.getMessage(), e1);
				e1.printStackTrace();
			} catch (SQLException e1) {
				logger.error(e1.getMessage(), e1);
				e1.printStackTrace();
			} catch (NamingException e) {
				logger.error(e.getMessage(), e);
				e.printStackTrace();
			}

			for(Student student: studentsTakingExam){

				if(!studentIDNew.contains(student.getUserID())){
					try {
						examdao.removeStudentFromExam(student.getUserID(), examID);
					} catch (ClassNotFoundException e) {
						logger.error(e.getMessage(), e);
						e.printStackTrace();
					} catch (SQLException e) {
						logger.error(e.getMessage(), e);
						e.printStackTrace();
					} catch (NamingException e) {
						logger.error(e.getMessage(), e);
						e.printStackTrace();
					}
				}
			}

			for(String studentID: studentIDNew){

				try {
					examdao.addStudentToExam(studentID, exam.getExamID());
				} catch (ClassNotFoundException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (SQLException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (NamingException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}

			}



		}
		else{

			if(examType.equals("Real")){

				if(!examStudents.equals("0")){

					for(String studentID: studentIDNew){

						try {
							examdao.addStudentToExam(studentID, exam.getExamID());
						} catch (ClassNotFoundException e) {
							logger.error(e.getMessage(), e);
							e.printStackTrace();
						} catch (SQLException e) {
							logger.error(e.getMessage(), e);
							e.printStackTrace();
						} catch (NamingException e) {
							logger.error(e.getMessage(), e);
							e.printStackTrace();
						}

					}
				}
			}
			else if(examType.equals("Practice")){
				try {
					ArrayList<Student> students = userdao.retrieveStudentsByProfessor(professor.getUserID());
					for(Student student: students){
						examdao.addStudentToExam(student.getUserID(), exam.getExamID());
					}
				} catch (ClassNotFoundException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (SQLException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				} catch (NamingException e) {
					logger.error(e.getMessage(), e);
					e.printStackTrace();
				}
			}

		}
		ArrayList<Message> messages = (ArrayList<Message>) session.getAttribute("messages");
		if(editMode){
			Message msg = new Message("Exam "+exam.getExamID()+ " Successfully Edited", "success");
			messages.add(0, msg);
			response.sendRedirect("ProfessorViewExamServlet?type="+examType+"&msg=Exam+Edited+Successfully&msgtype=success");
		}
		else{
			Message msg = new Message("Exam "+exam.getExamID()+ " Successfully Added", "success");
			messages.add(0, msg);
			response.sendRedirect("ProfessorViewExamServlet?type="+examType+"&msg=Exam+Added+Successfully&msgtype=success");

		}

	}

}
